
import java.awt.AWTException;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLException;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.filechooser.FileFilter;

import com.sun.opengl.util.*; 

public class JOGLSphericalTest extends JPanel implements GLEventListener, KeyListener, MouseMotionListener, MouseListener {

	protected float pyramidRotation;
	protected float cubeRotation;
	int x,y,startX,startY;
	int mouseDown = 0;
	
	final double PI = 3.14159265358979323846;
	final double PI_DIV_180 = 0.017453292519943296;
	final double deg = PI_DIV_180;
	double trot = 30;
	double prot = 30;
	double r = 1.0;
	float strafeX = 0.0f;
	float strafeY = 0.0f;
	float strafeZ = 0.0f;
	int i = 0;
	
	String extension;
	String filePath;
	
	boolean screenShot = false;
	boolean copyMol = false;
	
	private int windowHeight = 600;
	private int windowWidth = 800;
	
	GL screenShotContext;
	
	Oxygen oxygen = new Oxygen();
    Hydrogen hydrogen = new Hydrogen();
	
	public void display(GLAutoDrawable drawable) {
		final GL gl = drawable.getGL();
		final GLU glu = new GLU();
		gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
		

		gl.glEnable(GL.GL_LIGHTING);
		gl.glEnable(GL.GL_LIGHT0);
		
		gl.glLoadIdentity();
		gl.glTranslatef(0.0f, 0.0f, -1.0f);
	    //drawSpheres(gl);
		draw(gl,glu);			
						
	}
	
	protected void drawSpheres(GL gl, GLU glu){
		GLUT glut = new GLUT();
		
		
	    GLUquadric test; 
	    test = glu.gluNewQuadric();
	    //gl.glColor3f(1.0f, 0.0f, 0.0f);
	    gl.glColor3f(1.0f, 0.5f, 0.75f);
	    
	   /* float ambient[] = {0.3f, 0.0f, 0.0f, 1.0f};
	    float diffuse[] = {0.6f, 0.0f, 0.0f, 1.0f};
	    float specular[] = {0.8f, 0.6f, 0.6f, 1.0f};
	    float emission[] = {0.0f, 0.0f, 0.0f, 1.0f};
	    float shininess[] = {32.0f};*/
	
	    
	    //Object template list for abstractatom type
	    
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_AMBIENT,oxygen.ambient, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_DIFFUSE,oxygen.diffuse, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_SPECULAR,oxygen.specular, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_EMISSION,oxygen.emission, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_SHININESS,oxygen.shininess, 0);
	    
	    glu.gluQuadricDrawStyle(test,GLU.GLU_FILL);
	    glu.gluQuadricNormals(test,GLU.GLU_SMOOTH);
	    glu.gluSphere(test, 0.2, 100, 100);
	    
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_AMBIENT,hydrogen.ambient, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_DIFFUSE,hydrogen.diffuse, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_SPECULAR,hydrogen.specular, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_EMISSION,hydrogen.emission, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_SHININESS,hydrogen.shininess, 0);
	    
	    gl.glPushMatrix();
	    gl.glTranslatef(.5f, .5f, .5f);
	    glu.gluSphere(test, .2, 100, 100);
	    gl.glPopMatrix();
	    
	    Carbon carbon = new Carbon();
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_AMBIENT,carbon.ambient, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_DIFFUSE,carbon.diffuse, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_SPECULAR,carbon.specular, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_EMISSION,carbon.emission, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_SHININESS,carbon.shininess, 0);
	    
	    
	    gl.glPushMatrix();
	    //gl.glTranslatef(0.5f, 0.5f, 0.5f);
	    gl.glRotatef(55,-1,1,0);
	    glut.glutSolidCylinder(0.075f, 0.7f, 50, 50);
	    gl.glPopMatrix();
	    
	    gl.glPushMatrix();
	    gl.glRotatef(125f,-1f,-1f,0f);
	    glut.glutSolidCylinder(0.075f, 0.7f, 50, 50);
	    gl.glPopMatrix();
	    
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_AMBIENT,hydrogen.ambient, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_DIFFUSE,hydrogen.diffuse, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_SPECULAR,hydrogen.specular, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_EMISSION,hydrogen.emission, 0);
	    gl.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_SHININESS,hydrogen.shininess, 0);
	    
	    gl.glPushMatrix();
	    gl.glTranslatef(-0.5f, 0.5f, -0.5f);
	    glu.gluSphere(test, .2, 100, 100);
	    gl.glPopMatrix();
	    
	    if(screenShot == true)
		{	
	    	
	    	int writeToFile = initFileChooser(new File("."));
	    	
	    	if(writeToFile == 1)
	    	{
	    	try {
				Screenshot.writeToFile(new File(filePath+"."+extension),windowWidth, windowHeight);
			} catch (GLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
	    	}
	    	screenShot = false;
	    	
	    	
		}
	   
	    if(copyMol == true)
	    {
	    	BufferedImage image = Screenshot.readToBufferedImage(windowWidth, windowHeight);
	    	setClipboard(image);
	    	copyMol = false;
	    }
	
	}
	protected void draw(GL gl,GLU glu)
	{
		glu.gluLookAt(r*Math.cos(prot*deg)*Math.cos(trot*deg),r*Math.sin(prot*deg),r*Math.cos(prot*deg)*Math.sin(trot*deg), 0,0,0, -r*Math.sin(prot*deg)*Math.cos(trot*deg),r*Math.cos(prot*deg),-r*Math.sin(prot*deg)*Math.sin(trot*deg));
		//gl.glTranslatef(strafeX,strafeY,strafeZ);
		drawSpheres(gl,glu);
		
	}
	
		public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {

	}

	public void init(GLAutoDrawable drawable) {
		final GL gl = drawable.getGL();
		final GLCapabilities caps = new GLCapabilities();

		
		caps.setDoubleBuffered(true);
		gl.glShadeModel(GL.GL_SMOOTH);
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		gl.glClearDepth(1.0f);
		gl.glEnable(GL.GL_DEPTH_TEST);
		gl.glDepthFunc(GL.GL_LEQUAL);
		gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
		drawable.addKeyListener(this);
		drawable.addMouseListener(this);
		drawable.addMouseMotionListener(this);
		
	
		
	}
	
	 public void keyPressed(KeyEvent e) {
			if(e.getKeyCode() == KeyEvent.VK_W) {
				r-=0.1;
				if(r <= 0.1) 
				{r= 0.1;}			
			}
			
			if(e.getKeyCode() == KeyEvent.VK_S) {
			    r+=0.1;
			}
			
			if(e.getKeyCode() == KeyEvent.VK_A) {
			    trot += 3.0;
			}
			
			if(e.getKeyCode() == KeyEvent.VK_D) {
			    trot -= 3.0;
			}
			
			if(e.getKeyCode() == KeyEvent.VK_F1) {
			    screenShot = true;
			}
			
			if((e.getKeyCode() == KeyEvent.VK_C) && (e.getModifiers() == KeyEvent.CTRL_MASK))
			{
				copyMol = true;
			}
			if(e.getKeyCode() == KeyEvent.VK_1)
			{
				float amb[] = {0.3f, 0.0f, 0.0f, 1.0f};
				float dif[] = {0.3f, 0.01f, 0.0f, 1.0f};
				float spec[] = {0.8f, 0.6f, 0.6f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				oxygen.setAmbient(amb);
				oxygen.setDiffuse(dif);
				oxygen.setSpecular(spec);
				oxygen.setEmission(emis);
				
			}
			if(e.getKeyCode() == KeyEvent.VK_2)
			{
				float amb[] = {0.3f, 0.3f, 0.3f, 1.0f};
				float dif[] = {0.6f, 0.6f, 0.6f, 1.0f};
				float spec[] = {0.8f, 0.8f, 0.8f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				oxygen.setAmbient(amb);
				oxygen.setDiffuse(dif);
				oxygen.setSpecular(spec);
				oxygen.setEmission(emis);
			}
			if(e.getKeyCode() == KeyEvent.VK_3)
			{
				float amb[] = {0.0f, 1.0f, 0.0f, 1.0f};
				float dif[] = {0.0f, 0.6f, 0.0f, 1.0f};
				float spec[] = {0.6f, 0.8f, 0.6f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				oxygen.setAmbient(amb);
				oxygen.setDiffuse(dif);
				oxygen.setSpecular(spec);
				oxygen.setEmission(emis);
			}
			if(e.getKeyCode() == KeyEvent.VK_4)
			{
				float amb[] = {0.0f, 0.0f, 0.0f, 1.0f};
				float dif[] = {0.598f, 0.848f, 0.914f, 1.0f};
				float spec[] = {0.8f, 0.6f, 0.6f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				oxygen.setAmbient(amb);
				oxygen.setDiffuse(dif);
				oxygen.setSpecular(spec);
				oxygen.setEmission(emis);
			}
			if(e.getKeyCode() == KeyEvent.VK_5)
			{
				float amb[] = {0.8f, 0.8f, 0.8f, 1.0f};
				float dif[] = {1.0f, 1.0f, 1.0f, 1.0f};
				float spec[] = {1.0f, 1.0f, 1.0f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				oxygen.setAmbient(amb);
				oxygen.setDiffuse(dif);
				oxygen.setSpecular(spec);
				oxygen.setEmission(emis);
			}
			if(e.getKeyCode() == KeyEvent.VK_6)
			{
				float amb[] = {0.0f, 0.0f, 0.3f, 1.0f};
				float dif[] = {0.0f, 0.0f, 0.6f, 1.0f};
				float spec[] = {0.6f, 0.6f, 0.8f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				oxygen.setAmbient(amb);
				oxygen.setDiffuse(dif);
				oxygen.setSpecular(spec);
				oxygen.setEmission(emis);
			}
			if(e.getKeyCode() == KeyEvent.VK_7)
			{
				float amb[] = {0.3f, 0.0f, 0.0f, 1.0f};
				float dif[] = {0.6f, 0.0f, 0.0f, 1.0f};
				float spec[] = {0.8f, 0.6f, 0.6f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				oxygen.setAmbient(amb);
				oxygen.setDiffuse(dif);
				oxygen.setSpecular(spec);
				oxygen.setEmission(emis);
			}
			if(e.getKeyCode() == KeyEvent.VK_8)
			{
				float amb[] = {0.3f, 0.3f, 0.0f, 1.0f};
				float dif[] = {0.945f, 0.906f, 0.133f, 1.0f};
				float spec[] = {0.4f, 0.3f, 0.3f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				oxygen.setAmbient(amb);
				oxygen.setDiffuse(dif);
				oxygen.setSpecular(spec);
				oxygen.setEmission(emis);	
			}
				
			if(e.getKeyCode() == KeyEvent.VK_9)
			{
				float amb[] = {0.3f, 0.0f, 0.0f, 1.0f};
				float dif[] = {0.3f, 0.08f, 0.0f, 1.0f};
				float spec[] = {0.8f, 0.6f, 0.6f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				oxygen.setAmbient(amb);
				oxygen.setDiffuse(dif);
				oxygen.setSpecular(spec);
				oxygen.setEmission(emis);	
			}
			
			if((e.getKeyCode() == KeyEvent.VK_Q) && (e.getModifiers() == KeyEvent.CTRL_MASK))
			{
				float amb[] = {0.3f, 0.0f, 0.0f, 1.0f};
				float dif[] = {0.3f, 0.01f, 0.0f, 1.0f};
				float spec[] = {0.8f, 0.6f, 0.6f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				hydrogen.setAmbient(amb);
				hydrogen.setDiffuse(dif);
				hydrogen.setSpecular(spec);
				hydrogen.setEmission(emis);
			}
			
			if((e.getKeyCode() == KeyEvent.VK_E) && (e.getModifiers() == KeyEvent.CTRL_MASK))
			{
				float amb[] = {0.3f, 0.3f, 0.3f, 1.0f};
				float dif[] = {0.6f, 0.6f, 0.6f, 1.0f};
				float spec[] = {0.8f, 0.8f, 0.8f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				hydrogen.setAmbient(amb);
				hydrogen.setDiffuse(dif);
				hydrogen.setSpecular(spec);
				hydrogen.setEmission(emis);
			}
			
			if((e.getKeyCode() == KeyEvent.VK_R) && (e.getModifiers() == KeyEvent.CTRL_MASK))
			{
				float amb[] = {0.0f, 1.0f, 0.0f, 1.0f};
				float dif[] = {0.0f, 0.6f, 0.0f, 1.0f};
				float spec[] = {0.6f, 0.8f, 0.6f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				hydrogen.setAmbient(amb);
				hydrogen.setDiffuse(dif);
				hydrogen.setSpecular(spec);
				hydrogen.setEmission(emis);
			}
			
			if((e.getKeyCode() == KeyEvent.VK_T) && (e.getModifiers() == KeyEvent.CTRL_MASK))
			{
				float amb[] = {0.0f, 0.0f, 0.0f, 1.0f};
				float dif[] = {0.598f, 0.848f, 0.914f, 1.0f};
				float spec[] = {0.8f, 0.6f, 0.6f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				hydrogen.setAmbient(amb);
				hydrogen.setDiffuse(dif);
				hydrogen.setSpecular(spec);
				hydrogen.setEmission(emis);
			}
			
			if((e.getKeyCode() == KeyEvent.VK_Y) && (e.getModifiers() == KeyEvent.CTRL_MASK))
			{
				float amb[] = {0.8f, 0.8f, 0.8f, 1.0f};
				float dif[] = {1.0f, 1.0f, 1.0f, 1.0f};
				float spec[] = {1.0f, 1.0f, 1.0f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
			    hydrogen.setAmbient(amb);
				hydrogen.setDiffuse(dif);
				hydrogen.setSpecular(spec);
				hydrogen.setEmission(emis);
			}
			
			if((e.getKeyCode() == KeyEvent.VK_U) && (e.getModifiers() == KeyEvent.CTRL_MASK))
			{
				float amb[] = {0.0f, 0.0f, 0.3f, 1.0f};
				float dif[] = {0.0f, 0.0f, 0.6f, 1.0f};
				float spec[] = {0.6f, 0.6f, 0.8f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				hydrogen.setAmbient(amb);
				hydrogen.setDiffuse(dif);
				hydrogen.setSpecular(spec);
				hydrogen.setEmission(emis);
			}
			
			if((e.getKeyCode() == KeyEvent.VK_I) && (e.getModifiers() == KeyEvent.CTRL_MASK))
			{
				float amb[] = {0.3f, 0.0f, 0.0f, 1.0f};
				float dif[] = {0.3f, 0.01f, 0.0f, 1.0f};
				float spec[] = {0.8f, 0.6f, 0.6f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				hydrogen.setAmbient(amb);
				hydrogen.setDiffuse(dif);
				hydrogen.setSpecular(spec);
				hydrogen.setEmission(emis);
			}
			
			if((e.getKeyCode() == KeyEvent.VK_O) && (e.getModifiers() == KeyEvent.CTRL_MASK))
			{
				float amb[] = {0.3f, 0.3f, 0.0f, 1.0f};
				float dif[] = {0.945f, 0.906f, 0.133f, 1.0f};
				float spec[] = {0.4f, 0.3f, 0.3f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				hydrogen.setAmbient(amb);
				hydrogen.setDiffuse(dif);
				hydrogen.setSpecular(spec);
				hydrogen.setEmission(emis);
			}
			
			if((e.getKeyCode() == KeyEvent.VK_P) && (e.getModifiers() == KeyEvent.CTRL_MASK))
			{
				float amb[] = {0.3f, 0.0f, 0.0f, 1.0f};
				float dif[] = {0.3f, 0.08f, 0.0f, 1.0f};
				float spec[] = {0.8f, 0.6f, 0.6f, 1.0f};
				float emis[] = {0.0f, 0.0f, 0.0f, 1.0f};
				hydrogen.setAmbient(amb);
				hydrogen.setDiffuse(dif);
				hydrogen.setSpecular(spec);
				hydrogen.setEmission(emis);
			}
			
		    }

	 

	 public int initFileChooser(File currentDir)
		{
			JFileChooser fileChooser = new JFileChooser();
			
			int choice = 0;
			
			fileChooser.setCurrentDirectory(currentDir);
			
			ExtensionFileFilter jpegFilter = new ExtensionFileFilter("JPEG - *.jpg","JPG");
			ExtensionFileFilter bmpFilter = new ExtensionFileFilter("Bitmap - *.bmp","Bitmap");
			ExtensionFileFilter pngFilter = new ExtensionFileFilter("PNG - *.png","PNG");
			ExtensionFileFilter gifFilter = new ExtensionFileFilter("GIF - *.gif","GIF");
			
			fileChooser.addChoosableFileFilter(bmpFilter);
			fileChooser.addChoosableFileFilter(gifFilter);
			fileChooser.addChoosableFileFilter(jpegFilter);
			fileChooser.addChoosableFileFilter(pngFilter);
			
			fileChooser.setAcceptAllFileFilterUsed(false);
			
			fileChooser.setFileFilter(jpegFilter);
			
			
			int result = fileChooser.showSaveDialog(null);
			if (result == JFileChooser.APPROVE_OPTION)
			{
				FileFilter testFilter = fileChooser.getFileFilter();
				extension = testFilter.getDescription();
				int dotPos = extension.lastIndexOf(".");
				extension = extension.substring(dotPos+1);
				System.out.println(extension);
				
				File file = fileChooser.getSelectedFile();
				System.out.println(file.getAbsolutePath());
				
				
				boolean exists = (new File(file.getAbsolutePath()+"."+extension)).exists();
				System.out.println(exists);
				if(exists)
				{
					int selection;
					//JOptionPane testPane = new JOptionPane();
					selection = JOptionPane.showConfirmDialog(null, file.getName()+"."+extension+" already exists\n"
							+ "Would you like to overwrite the existing file?");
					if (selection == JOptionPane.YES_OPTION)
					{
						choice = 1;
						filePath = file.getAbsolutePath();
						/*try {
							canvas.testScreen(file,extension);
							
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						} catch (AWTException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}*/
					}
					else
					{
						initFileChooser(fileChooser.getCurrentDirectory());
					}
					
					
				}
				else
				{
					filePath = file.getAbsolutePath();
					choice = 1;
				}
					
				
				
			}
			
			return choice;
		}
		 
		    public void keyReleased(KeyEvent e) {
		    }
		 
		    public void keyTyped(KeyEvent e) {
		    }


		    
			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseEntered(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseExited(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mousePressed(MouseEvent e) {
				
				startX = e.getX();
			    startY = e.getY();
			    
			   // maybeShowPopup(e);
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void mouseDragged(MouseEvent e) {
		    	
				int x = e.getX();
			    int y = e.getY();
				
				trot += (x-startX)/2;
		        //if (trot > 360) trot -= 360;
		       // if (trot < 0) trot += 360;
		        startX = x;

		        prot += (y-startY)/2;
		        //if (prot < -90) prot = -90;
		       // if (prot > 90) prot = 90;
		        startY = y;
		        
		        			
			}

			@Override
			public void mouseMoved(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}
		    
		    
	public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
		final GL gl = drawable.getGL();
		final GLU glu = new GLU();
		
		windowWidth = width;
		windowHeight = height;
		
		gl.setSwapInterval(0);

		gl.glViewport(0, 0, width, height);
		gl.glMatrixMode(GL.GL_PROJECTION);
		gl.glLoadIdentity();

		glu.gluPerspective(
				45.0f, 
				(double) width / (double) height, 
				0.1f,
				1000.0f);

		gl.glMatrixMode(GL.GL_MODELVIEW);
		gl.glLoadIdentity();
	}

	// This method writes a image to the system clipboard. // otherwise it returns null. public static void setClipboard(Image image) { ImageSelection imgSel = new ImageSelection(image); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(imgSel, null); } // This class is used to hold an image while on the clipboard. public static class ImageSelection implements Transferable { private Image image; public ImageSelection(Image image) { this.image = image; } // Returns supported flavors public DataFlavor[] getTransferDataFlavors() { return new DataFlavor[]{DataFlavor.imageFlavor}; } // Returns true if flavor is supported public boolean isDataFlavorSupported(DataFlavor flavor) { return DataFlavor.imageFlavor.equals(flavor); } // Returns image public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { if (!DataFlavor.imageFlavor.equals(flavor)) { throw new UnsupportedFlavorException(flavor); } return image; } } 	

	// This method writes a image to the system clipboard. 
	// otherwise it returns null. 
	public static void setClipboard(Image image) 
	{ 
		ImageSelection imgSel = new ImageSelection(image); 
		Toolkit.getDefaultToolkit().getSystemClipboard().setContents(imgSel, null); 
	
	} 
	// This class is used to hold an image while on the clipboard. 
	public static class ImageSelection implements Transferable 
	{ 
		private Image image; 
		
		public ImageSelection(Image image) 
		{ this.image = image; }

	@Override
	public Object getTransferData(DataFlavor flavor)
			throws UnsupportedFlavorException, IOException {
		if (!DataFlavor.imageFlavor.equals(flavor)) 
		{ 
			throw new UnsupportedFlavorException(flavor); 
		} 
		return image; 
		
	}

	@Override
	public DataFlavor[] getTransferDataFlavors() {
		return new DataFlavor[]{DataFlavor.imageFlavor}; 
	}

	@Override
	public boolean isDataFlavorSupported(DataFlavor flavor) {
		return DataFlavor.imageFlavor.equals(flavor);
	}  

	}
}